package com.cloud.custom.workflow.command.transit;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;

import com.cloud.custom.common.context.HumanSession;
import com.cloud.custom.common.exception.BizException;
import com.cloud.custom.common.utils.SessionHelper;
import com.cloud.custom.interfaces.FeignClientFreeflow;
import com.cloud.custom.workflow.bean.WfActDef;
import com.cloud.custom.workflow.command.Command;
import com.cloud.custom.workflow.command.WfRequest;
import com.cloud.custom.workflow.command.WfResponse;
import com.cloud.custom.workflow.entity.WfActChoice;
import com.cloud.custom.workflow.entity.WfActInst;
import com.cloud.custom.workflow.entity.WfItemInst;
import com.cloud.custom.workflow.entity.WfPerPart;
import com.cloud.custom.workflow.entity.WfTransInst;
import com.cloud.custom.workflow.enums.WfActStateEnum;
import com.cloud.custom.workflow.enums.WfItemTypeEnum;
import com.cloud.custom.workflow.enums.WfPartEnum;
import com.cloud.custom.workflow.mapper.WfActChoiceMapper;
import com.cloud.custom.workflow.mapper.WfActInstMapper;
import com.cloud.custom.workflow.mapper.WfItemInstMapper;
import com.cloud.custom.workflow.mapper.WfPerPartMapper;
import com.cloud.custom.workflow.mapper.WfTransInstMapper;

import tk.mybatis.mapper.entity.Example;

/**
 * 批转/移交指令
 * 
 * @author taominglong
 *
 */

public class TransitCommand extends Command {
	@Override
	public void execute(WfRequest request, WfResponse resp, ApplicationContext context) {
		TransitRequest transReq = (TransitRequest) request;
		HumanSession humanSession = SessionHelper.get();

		// 更新当前环节的流程实例
		WfActInstMapper wfActInstMapper = context.getBean(WfActInstMapper.class);
		Example example = new Example(WfActInst.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("actId", transReq.getActId());
		criteria.andEqualTo("actStateId", WfActStateEnum.PENDING.getActStateId());
		List<WfActInst> actInsts = wfActInstMapper.selectByExample(example);
		if (null == actInsts || actInsts.size() == 0) {
			throw new BizException(500, "流程实例不存在，请检查案卷是否已经批转");
		}
		WfActInst actInst = actInsts.get(0);
		actInst.setActStateId(WfActStateEnum.PROCESSED.getActStateId());
		actInst.setActStateName(WfActStateEnum.PROCESSED.getActStateName());
		wfActInstMapper.updateByPrimaryKey(actInst);

		FeignClientFreeflow feignClientFreeFlow = context.getBean(FeignClientFreeflow.class);
		WfActDef nextActDef = feignClientFreeFlow.loadProcActDef(transReq.getNextActDefId());

		// 增加最新环节的流程实例
		WfActInst currentActInst = new WfActInst();
		BeanUtils.copyProperties(nextActDef, currentActInst);
		currentActInst.setPerActDefId(actInst.getActDefId());
		currentActInst.setPerActId(actInst.getActId());
		currentActInst.setPartId(transReq.getNextPartId());
		currentActInst.setPartName(transReq.getNextPartName());
		currentActInst.setCreateTime(new Date());
		if (StringUtils.isEmpty(transReq.getNextPartType())) {
			currentActInst.setPartType(WfPartEnum.HUMAN.getPartType());
		} else {
			currentActInst.setPartType(transReq.getNextPartType());
		}
		currentActInst.setPerHumanId(actInst.getPartId());
		currentActInst.setPerHumanName(actInst.getPartName());
		currentActInst.setRecId(transReq.getRecId());
		currentActInst.setOpinion(transReq.getOpinion());
		currentActInst.setActStateId(WfActStateEnum.PENDING.getActStateId());
		currentActInst.setActStateName(WfActStateEnum.PENDING.getActStateName());
		wfActInstMapper.insert(currentActInst);

		// 添加当前环节的经办人
		WfPerPartMapper wfPerPartMapper = context.getBean(WfPerPartMapper.class);
		WfPerPart perPart = new WfPerPart();
		perPart.setHumanId(humanSession.getHumanId());
		perPart.setRecId(transReq.getRecId());
		if (!wfPerPartMapper.existsWithPrimaryKey(perPart)) {
			wfPerPartMapper.insert(perPart);
		}

		// 添加当前环节的工作项
		WfItemInstMapper wfItemInstMapper = context.getBean(WfItemInstMapper.class);
		WfItemInst itemInst = new WfItemInst();
		itemInst.setActId(currentActInst.getActId());
		itemInst.setActDefId(actInst.getActDefId());
		itemInst.setActDefName(actInst.getActDefName());
		itemInst.setActionTime(new Date());
		itemInst.setActionName("提交");
		itemInst.setDetail(humanSession.getHumanName() + "在" + actInst.getActDefName() + "阶段执行提交");
		itemInst.setItemContent(transReq.getOpinion());
		itemInst.setHumanId(humanSession.getHumanId());
		itemInst.setHumanName(humanSession.getHumanName());
		itemInst.setItemTypeId(WfItemTypeEnum.TRANSIT.getItemTypeId());
		itemInst.setItemTypeName(WfItemTypeEnum.TRANSIT.getItemTypeName());
		itemInst.setRecId(transReq.getRecId());
		wfItemInstMapper.insert(itemInst);

		// 添加当前环节流向实例
		WfTransInstMapper wfTransInstMapper = context.getBean(WfTransInstMapper.class);
		WfTransInst transInst = new WfTransInst();
		transInst.setTransDefId(transReq.getTransDefId());
		transInst.setFromActDefName(actInst.getActDefName());
		transInst.setFromActDefId(actInst.getActDefId());
		transInst.setFromActId(actInst.getActId());
		transInst.setToActId(currentActInst.getActId());
		transInst.setToActDefId(currentActInst.getActDefId());
		transInst.setToActDefName(currentActInst.getActDefName());
		transInst.setNextPartId(currentActInst.getPartId());
		transInst.setNextPartName(currentActInst.getPartName());
		transInst.setNextPartType(currentActInst.getPartType());
		transInst.setCreateTime(new Date());
		transInst.setHumanId(humanSession.getHumanId());
		transInst.setHumanName(humanSession.getHumanName());
		transInst.setItemTypeId(WfItemTypeEnum.TRANSIT.getItemTypeId());
		transInst.setItemTypeName(WfItemTypeEnum.TRANSIT.getItemTypeName());
		transInst.setRecId(transReq.getRecId());
		wfTransInstMapper.insert(transInst);
		// 更新上一环节的工作项目
		Example itemExample = new Example(WfItemInst.class);
		Example.Criteria itemCriteria = itemExample.createCriteria();
		itemCriteria.andEqualTo("recId", transReq.getRecId());
		itemCriteria.andEqualTo("actId", actInst.getActId());
		List<WfItemInst> insts = wfItemInstMapper.selectByExample(itemExample);
		if (null != insts && insts.size() == 1) {
			WfItemInst inst = insts.get(0);
			inst.setNextActId(currentActInst.getActId());
			inst.setNextActDefId(transReq.getNextActDefId() + "");
			inst.setNextActDefName(transReq.getNextActDefName());
			inst.setNextPartId(transReq.getNextPartId() + "");
			inst.setNextPartName(transReq.getNextPartName());
			if (StringUtils.isEmpty(transReq.getNextPartType())) {
				inst.setNextPartType(WfPartEnum.HUMAN.getPartType());
			} else {
				inst.setNextPartType(transReq.getNextPartType());
			}
			wfItemInstMapper.updateByPrimaryKey(inst);
		}
		// 添加环节流向常用批转对象
		WfActChoiceMapper wfActChoiceMapper = context.getBean(WfActChoiceMapper.class);
		WfActChoice choice = new WfActChoice();
		choice.setHumanId(SessionHelper.get().getHumanId());
		choice.setActDefId(actInst.getActDefId());
		choice.setTargetPartId(transReq.getNextPartId());
		choice.setTargetActDefId(transReq.getNextActDefId());
		if (wfActChoiceMapper.existsWithPrimaryKey(choice)) {
			choice = wfActChoiceMapper.selectByPrimaryKey(choice);
			choice.setFrequency(choice.getFrequency() + 1);
			wfActChoiceMapper.updateByPrimaryKey(choice);
		} else {
			choice.setTargetActDefName(transReq.getNextActDefName());
			choice.setTargetPartName(transReq.getNextPartName());
			choice.setFrequency(1);
			wfActChoiceMapper.insert(choice);
		}

		TransitResponse transResp = (TransitResponse) resp;
		transResp.setRecId(transReq.getRecId());
		transResp.setActId(currentActInst.getActId());
		transResp.setActDef(nextActDef);
	}
}
